from __future__ import absolute_import

__all__ = ('Breadcrumbs', )

from sentry.interfaces.base import Interface, prune_empty_keys
from sentry.utils.safe import get_path
from sentry.utils.dates import to_timestamp, to_datetime, parse_timestamp


class Breadcrumbs(Interface):
    """
    This interface stores information that leads up to an error.

    - ``message`` must be no more than 1000 characters in length.

    >>> [{
    >>>     "type": "message",
    >>>     // timestamp can be ISO format or a unix timestamp (as float)
    >>>     "timestamp": "2016-01-17T12:30:00",
    >>>     "data": {
    >>>         "message": "My raw message with interpreted strings like %s",
    >>>     }
    >>> ], ...}
    """
    display_score = 1100
    score = 800

    @classmethod
    def to_python(cls, data):
        values = []
        for index, crumb in enumerate(get_path(data, 'values', filter=True, default=())):
            # TODO(ja): Handle already invalid and None breadcrumbs
            values.append(cls.normalize_crumb(crumb))

        return cls(values=values)

    def to_json(self):
        return prune_empty_keys({
            'values': [
                prune_empty_keys({
                    'type': crumb['type'],
                    'level': crumb['level'],
                    'timestamp': crumb['timestamp'],
                    'message': crumb['message'],
                    'category': crumb['category'],
                    'event_id': crumb['event_id'],
                    'data': crumb['data'] or None
                }) for crumb in self.values
            ] or None
        })

    @classmethod
    def normalize_crumb(cls, crumb):
        crumb = dict(crumb)
        ts = parse_timestamp(crumb.get('timestamp'))
        if ts:
            crumb['timestamp'] = to_timestamp(ts)
        else:
            crumb['timestamp'] = None

        for key in (
            'type',
            'level',
            'message',
            'category',
            'event_id',
            'data',
        ):
            crumb.setdefault(key, None)

        return crumb

    def get_api_context(self, is_public=False, platform=None):
        def _convert(x):
            return {
                'type': x['type'],
                'timestamp': x['timestamp'] and to_datetime(x['timestamp']),
                'level': x.get('level', 'info'),
                'message': x.get('message'),
                'category': x.get('category'),
                'data': x.get('data') or None,
                'event_id': x.get('event_id'),
            }

        return {
            'values': [_convert(v) for v in self.values],
        }

    def get_api_meta(self, meta, is_public=False, platform=None):
        if meta and 'values' not in meta:
            return {'values': meta}
        else:
            return meta
